package io.keyss.view_record.recording

import android.media.MediaCodec
import android.media.MediaFormat
import android.media.MediaMuxer
import java.nio.ByteBuffer
import android.util.Log

class AudioVideoMp4Encoder(private val filePath: String) {
    private val muxer = MediaMuxer(filePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4)
    private var videoTrack = -1
    private var audioTrack = -1
    private var started = false
    private var videoFormat: MediaFormat? = null
    private var audioFormat: MediaFormat? = null
    private val TAG = "AVMp4Encoder"

    @Synchronized
    fun addVideoTrack(format: MediaFormat) {
        if (videoTrack == -1) {
            videoTrack = muxer.addTrack(format)
            videoFormat = format
            Log.d(TAG, "addVideoTrack: index=$videoTrack, format=$format")
            tryStart()
        }
    }

    @Synchronized
    fun addAudioTrack(format: MediaFormat) {
        if (audioTrack == -1) {
            audioTrack = muxer.addTrack(format)
            audioFormat = format
            Log.d(TAG, "addAudioTrack: index=$audioTrack, format=$format")
            tryStart()
        }
    }

    @Synchronized
    private fun tryStart() {
        Log.d(TAG, "tryStart: videoTrack=$videoTrack, audioTrack=$audioTrack, started=$started")
        if (!started && videoTrack != -1 && audioTrack != -1) {
            muxer.start()
            started = true
            Log.d(TAG, "muxer started!")
        }
    }

    @Synchronized
    fun writeVideoSample(buffer: ByteBuffer, info: MediaCodec.BufferInfo) {
        if (started && videoTrack != -1 && info.size > 0) {
            Log.d(TAG, "writeVideoSample: pts=${info.presentationTimeUs}, size=${info.size}, flags=${info.flags}")
            muxer.writeSampleData(videoTrack, buffer, info)
        } else {
            Log.d(TAG, "writeVideoSample: skipped, started=$started, videoTrack=$videoTrack, size=${info.size}")
        }
    }

    @Synchronized
    fun writeAudioSample(buffer: ByteBuffer, info: MediaCodec.BufferInfo) {
        if (started && audioTrack != -1 && info.size > 0) {
            Log.d(TAG, "writeAudioSample: pts=${info.presentationTimeUs}, size=${info.size}, flags=${info.flags}")
            muxer.writeSampleData(audioTrack, buffer, info)
        } else {
            Log.d(TAG, "writeAudioSample: skipped, started=$started, audioTrack=$audioTrack, size=${info.size}")
        }
    }

    @Synchronized
    fun release() {
        Log.d(TAG, "release: started=$started")
        if (started) {
            try {
                muxer.stop()
                Log.d(TAG, "muxer stopped")
            } catch (e: Exception) {
                Log.e(TAG, "muxer stop error", e)
            }
            try {
                muxer.release()
                Log.d(TAG, "muxer released")
            } catch (e: Exception) {
                Log.e(TAG, "muxer release error", e)
            }
            started = false
        }
    }
} 